package ejb.com.bbva.cbm.util;

import java.io.File;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import oracle.jdbc.driver.OracleTypes;

import org.apache.log4j.Logger;

import cbm.commons.Conexion;
import cbm.commons.UtilitarioFunciones;
import ejb.cbm.admin.bean.ProcesoBean;
import ejb.cbm.commons.JdbcHelper;
import ejb.com.bbva.cbm.service.CorreoService;
import ejb.com.bbva.cbm.service.ejb.CorreoServiceImpl;

public class HiloEjecucionCargaArchivo implements Runnable {

	private static Logger logger = Logger.getLogger(HiloEjecucionCargaArchivo.class.getName());
	private Long archivoId;
	private String procedimiento;
	private String nombreTabla;
	private String nombreFuente;
	private String extension;
	private String dir;
	private String origen;
	private String destino;
		
	public HiloEjecucionCargaArchivo(ProcesoBean proceso) {
		this.archivoId = proceso.getCodigo();
		this.procedimiento = proceso.getProcedimiento();
		this.nombreTabla = proceso.getNombreTabla();
		this.nombreFuente = proceso.getNombreFuente();
		this.extension = proceso.getExtension();
		this.dir = proceso.getDir();
	}
	
	private boolean renombraArchivo() {
		boolean estado = true;
		SimpleDateFormat fmt = new SimpleDateFormat("yyMMdd");
		
		try {
			this.dir = this.dir.replace("\\", "/");
			if (!this.dir.endsWith("/")) {
				this.dir += "/";
			}
			
			this.origen = this.nombreFuente + fmt.format(new Date()) + "." + this.extension;
			this.destino = this.nombreFuente + "." + this.extension;
			this.nombreTabla = this.origen.toString();
			
			File fOrigen = new File(this.dir + this.origen);
			File fDestino = new File(this.dir + this.destino);
			
			fOrigen.renameTo(fDestino);
		} catch(Exception e) {
			logger.error("Error al renombrar el archivo", e);
			estado = false;
		}
		
		return estado;
	}
	
	private boolean revertirNombreArchivo() {
		boolean estado = true;
		
		try {
			File fOrigen = new File(this.dir + this.destino);			
			File fDestino = new File(this.dir + this.origen);
			
			fOrigen.renameTo(fDestino);
		} catch(Exception e) {
			logger.error("Error al revertir el nombre del archivo", e);
			estado = false;
		}
		
		return estado;
	}
	
	public void run() {
		logger.info("HiloEjecucionCargaArchivo.run: Inicio Carga Archivo [archivoId=" + archivoId + "]");
		
		SimpleDateFormat  fmt = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
		Connection        cnn = null;
		CallableStatement stm = null;
		ResultSet         rst = null;
		boolean tomoArchivo = false;
		String sql = "";
		Long idLote = 0L;
		logger.debug("CONNEG - Ejecutando Hilo Programacion");
		try {
			renombraArchivo();
			
			//1.- REALIZAMOS EL PROCESO DE CARGA
			sql = "{call CONNEG." + procedimiento + "(?,?,?,?)}";
			cnn = Conexion.getConnection();
			stm = cnn.prepareCall(sql);
			logger.info("CONNEG - " + sql);
			stm.setLong(1, archivoId);
			stm.setString(2, nombreTabla);
			stm.registerOutParameter(3, OracleTypes.INTEGER);
			stm.registerOutParameter(4, OracleTypes.CURSOR);
			stm.execute();
			tomoArchivo = stm.getBoolean(3);
			
			// TODO: Dejar traza en el log del app
			rst = (ResultSet) stm.getObject(4);
			
			try {
				int i = 0;
				if(rst != null) {
					while (rst.next()) {
						if(i == 0) {
							idLote = rst.getLong("ID_LOTE");
							logger.error("\n\n");
							logger.error("=================================================================================================================================");
							logger.error("Errores ocurridos durante el proceso de la ejecucion: [" + procedimiento + "]");
							logger.error("ID del lote: [" + rst.getString("ID_LOTE") + "]");
							logger.error("ID del archivo: [" + rst.getString("CODIGO_ARCHIVO") + "]");
							logger.error("=================================================================================================================================");
						}
						
						logger.error("Fecha Hora: [" + fmt.format(rst.getTime("FECHA_ERROR")) + "] Mensaje: " + rst.getString("MENSAJE_ERROR"));
						i++;
					}
					logger.error("\n\n");
				}
			} catch(Exception e) {
				logger.error("No se pudo obtener el archivo log del proceso", e);
			}
			
			try {
				stm.close();
			} catch(SQLException e) {
				logger.error("No se pudo cerrar.", e);
			}
			
			revertirNombreArchivo();
			
			sql = "{call CONNEG.PQ_ARCHIVO.SP_LIMPIAR_LOG_ERROR(?, ?)}";
			stm = cnn.prepareCall(sql);
			logger.info("CONNEG - " + sql);
			stm.setLong(1, archivoId);
			stm.setLong(2, idLote);
			stm.execute();	
			
			JdbcHelper.close(cnn, stm);
		} catch (Exception e) {
			JdbcHelper.close(cnn, stm);
			logger.error("HiloEjecucionCargaArchivo.run: Error Carga Archivo [archivoId=" + archivoId + "]");
			logger.error("CONNEG - ERROR EN INVOCACION DE CARGA ", e);
		}
		
		try{
			cnn = Conexion.getConnection();
			stm = cnn.prepareCall("{call CONNEG.PQ_ARCHIVO.SP_DATOS_CORREO_ARCHIVOS(?,?,?,?,?,?)}");
			stm.setLong(1, archivoId);
			stm.registerOutParameter(2, OracleTypes.VARCHAR);
			stm.registerOutParameter(3, OracleTypes.VARCHAR);
			stm.registerOutParameter(4, OracleTypes.DATE);
			stm.registerOutParameter(5, OracleTypes.DATE);			
			stm.registerOutParameter(6, OracleTypes.VARCHAR);			
			stm.execute();
			
			String nombreArchivo		=	stm.getString(2);			
			String resultadoCarga		=	stm.getString(3);
			Date fechaHoraInicioCarga	=	stm.getTimestamp(4);
			Date fechaHoraFinCarga		=	stm.getTimestamp(5);
			String correoPara		    =	stm.getString(6);
			
			JdbcHelper.close(cnn, stm);			
			
			//2.- ENVIAMOS EL CORREO DEL RESULTADO
			if (tomoArchivo) {
				Map<String, Object> parametros = new HashMap<String, Object>();
				parametros.put("<<nombreArchivo>>", nombreArchivo);
				parametros.put("<<resultadoEstadoCarga>>", resultadoCarga);
				parametros.put("<<fechaHoraInicioCarga>>", UtilitarioFunciones.convertirFechaHoraFormato(fechaHoraInicioCarga));
				parametros.put("<<fechaHoraFinCarga>>", UtilitarioFunciones.convertirFechaHoraFormato(fechaHoraFinCarga));
				parametros.put("<<duracionCarga>>", UtilitarioFunciones.fechasDiferenciaEnMinutos(fechaHoraInicioCarga,fechaHoraFinCarga)+"");
				parametros.put("<<correoPara>>", correoPara);
				CorreoService correoService = new CorreoServiceImpl();
				correoService.enviarCorreo(Constante.ENVI_CORR_CARGA_ARCHIVO_ID, parametros);
			}
		}catch (Exception e) {
			JdbcHelper.close(cnn, stm);	
			logger.error("call CONNEG.PQ_ARCHIVO.SP_DATOS_CORREO_ARCHIVOS", e);
		}
		logger.info("HiloEjecucionCargaArchivo.run: Fin Carga Archivo [archivoId=" + archivoId + "]");
	}
}
